using UnityEngine;
using UnityEngine.UIElements;

// 节点输入端插入输入字段代替端口功能 封装一个类,插入输入类型,自动保存数据和反加载 未实现
// 像是没有逻辑接口的节点,有输入输出端口,如果有其他节点获取输出信息,需要自动调用逻辑接口,获取数据 未实现
// 需要增加
// 增加输出节点值更新时事件

namespace XLFrame.NodeEditor
{

    #region If节点
    public class IfNode : NodeViewBase
    {
        public override string MenuPath => "流程控制/If";

        protected override void Init()
        {
            base.Init();
            title = "If";

        }

        protected override void InitializeForFirstCreation()
        {
            base.InitializeForFirstCreation();
            NodePort.CreateInputExecutionLinePort();
            NodePort.CreateOutputPort<ExecutionLine>("True");
            NodePort.CreateOutputPort<ExecutionLine>("False");

            NodePort.CreateInputPort<bool>("条件");

            NodeLogic.AddNodeLogic<IfNodeLogic>();
        }
    }

    

    #endregion

    #region debug节点
    
    public class DebugNode : NodeViewBase
    {
        public override string MenuPath => "调试/Debug";
        private Label log;
        protected override void Init()
        {
            base.Init();
            title = "控制台输出";
            
            // 填写推荐连接的端口 不填写默认根据端口类型匹配
            AddRecommendedPortNode<RandomNumNode>();
            AddInputRecommendedPortNode<AddNode>();


            log = new Label();
            extensionContainer.Add(log);
        }

        protected override void InitializeForFirstCreation()
        {
            base.InitializeForFirstCreation();

            NodePort.CreateInputExecutionLinePort();
            NodePort.CreateOutputExecutionLinePort();

            NodePort.CreateInputPort<object>("输入");

            NodeLogic.AddNodeLogic<DebugNodeLogic>();
        }

        protected override void OnExecuteEnd(INodeLogic nodeLogic)
        {
            base.OnExecuteEnd(nodeLogic);
            object obj = nodeLogic.GetInputData<object>("输入");
            if(obj == null)
            {
                log.text = "null";
                return;
            }
            else
            {
                log.text = nodeLogic.GetInputData<object>("输入").ToString();
            }
        }
    }

    #endregion

    #region Start节点

    public class StartNode : NodeViewBase
    {
        protected override void Init()
        {
            base.Init();
            title = "入口";
            // 药丸容器
            //var a = CreatePortForNode(Direction.Output, Port.Capacity.Single, typeof(float));
            //Pill pill = new Pill();
            //pill.text = "开始";
            //pill.right = a;

            //contentContainer.Add(pill);
            Button button = new Button(() =>
            {
                NodeLogic.Execute("null");
            });
            button.Add(new Label("开始"));
            extensionContainer.Add(button);
        }

        protected override void InitializeForFirstCreation()
        {
            base.InitializeForFirstCreation();
            NodePort.CreateOutputExecutionLinePort();

            NodeLogic.AddNodeLogic<StartNodeLogic>();
            
            NodeData.Attributes.SetAttribute("__节点类型", "开始");
        }
    }
    

    #endregion

    #region 随机模块
    public class RandomNumNode : NodeViewBase
    {
        public override string MenuPath => "工具/随机数模块";
        private Label log;

        protected override void Init()
        {
            base.Init();
            title = "随机数模块";

            log = new Label();
            extensionContainer.Add(log);

            Button removeButton = new Button();
            removeButton.Add(new Label("移除随机数端口"));
            removeButton.clicked += () =>
            {
                NodePort.RemovePort(NodePort.GetOutputPort("随机数").name, false);
            };
            
            Button addButton = new Button();
            addButton.Add(new Label("增加一个随机数端口"));
            addButton.clicked += () =>
            {
                NodePort.CreateOutputPort<int>("随机数");
            };
            
            extensionContainer.Add(removeButton);
            extensionContainer.Add(addButton);
        }

        protected override void OnAddView()
        {
            base.OnAddView();
            if(IsNewNode)
            {
                // 添加默认连接的输入节点
                NodePort.AddInputPortDefNode<InputIntNode>("最大值");
                NodePort.AddInputPortDefNode<InputIntNode>("最小值");
            }
        }

        protected override void OnExecuteEnd(INodeLogic nodeLogic)
        {
            base.OnExecuteEnd(nodeLogic);
            log.text = nodeLogic.GetOutputData<int>("随机数").ToString();
        }

        protected override void InitializeForFirstCreation()
        {
            base.InitializeForFirstCreation();
            NodePort.CreateInputExecutionLinePort();
            NodePort.CreateOutputExecutionLinePort();

            NodePort.CreateInputPort<int>("最小值");
            NodePort.CreateInputPort<int>("最大值");
            NodePort.CreateOutputPort<int>("随机数");

            NodeLogic.AddNodeLogic<RandomNumNodeLogic>();
            NodeStyle.AddNodeStyle<RandomNumNodeStyle>();
        }
    }

    public class RandomNumNodeStyle : NodeStyleBase
    {
        /// <summary>
        /// 子集重写用来编写样式
        /// </summary>
        protected override void OnNodeStyleInit()
        {
            style.backgroundColor = new Color(0.2f,0.25f,0.25f);
            style.minHeight = 10;

            Label title = new Label("样式测试");
            
            Add(title);
            
            Button removeButton = new Button();
            removeButton.Add(new Label("测试按钮"));
            removeButton.clicked += () =>
            {
                Debug.Log("测试按钮");
            };
            Add(removeButton);

            InputIntVE test = new InputIntVE("测试",999);
            InputLongVE test2 = new InputLongVE("测试2",999);
            InputFloatVE test3 = new InputFloatVE("测试3",999);
            InputStringVE test4 = new InputStringVE("测试4","999");
            InputBoolVE test5 = new InputBoolVE("测试5",true);
            InputVector2VE test6 = new InputVector2VE("测试6",Vector2.one);
            InputVector3VE test7 = new InputVector3VE("测试7",Vector3.one);
            InputVector2IntVE test8 = new InputVector2IntVE("测试8",Vector2Int.one);
            InputVector3IntVE test9 = new InputVector3IntVE("测试9",Vector3Int.one);
            InputVector4VE test10 = new InputVector4VE("测试10",Vector4.one);
            InputColorVE test11 = new InputColorVE("测试11",Color.red);
            InputTexture2DVE test12 = new InputTexture2DVE("测试12", 
                                                           NodeView.NodeData.Attributes.GetAttribute<Texture2D>("__Image"),
                                                           false);
            test12.OnValueChangedEvent += (b,o) =>
            {
                NodeView.NodeData.Attributes.SetAttribute("__Image", o);
            };
            
            ListInputVE<InputIntVE> test13 = new ListInputVE<InputIntVE>("测试13");

            Add(test);
            Add(test2);
            Add(test3);
            Add(test4);
            Add(test5);
            Add(test6);
            Add(test7);
            Add(test8);
            Add(test9);
            Add(test10);
            Add(test11);
            Add(test12);
            Add(test13);
        }

        protected override void OnIsNewNode()
        {
            var a = CreateOutputPort<int>("测试");
            StyleData.Attributes.SetAttribute("测试端口UID",a.name);
            Add(a);
        }

        protected override void OnIsNotNewNode()
        {
            Add(Ports[StyleData.Attributes.GetAttribute<string>("测试端口UID")]);
        }
    }

    

    #endregion


    #region 加法模块

    public class AddNode : NodeViewBase
    {
        public override string MenuPath => "工具/加法模块";

        protected override void Init()
        {
            base.Init();
            title = "加法模块";
        }

        protected override void InitializeForFirstCreation()
        {
            base.InitializeForFirstCreation();

            NodePort.CreateInputPort<float>("加数1");
            NodePort.CreateInputPort<float>("加数2");

            NodePort.CreateOutputPort<float>("和");

            NodeLogic.AddNodeLogic<AddNodeLogic>();
        }
    }
    #endregion

}
